package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private VodService vodService;

    @Autowired
    private AlbumInfoService albumInfoService;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Transactional
    @Override
    public void saveTrackInfo(TrackInfoVo trackInfoVo) {

        TrackInfo trackInfo = new TrackInfo();

        //## 第一部分 -- 声音基本信息：专辑id、用户id、标题、简介、封面等等
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
        System.out.println(AuthContextHolder.getUserId());
        trackInfo.setUserId(AuthContextHolder.getUserId());

        //## 第二部分数据 -- 到腾讯云找到，声音文件信息，大小、播放时长、类型
        //获取声音在腾讯云中的唯一id
        //获取流媒体信息
        String mediaFileId = trackInfoVo.getMediaFileId();
        TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackInfoTenx(mediaFileId);

        trackInfo.setMediaSize(trackMediaInfoVo.getSize());
        trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
        trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
        trackInfo.setMediaType(trackMediaInfoVo.getType());

        //## 第三部分数据 -- order_num，声音排序字段，每次添加声音，值+1
        TrackInfo trackInfoMaxNum = trackInfoMapper.selectOne(new LambdaQueryWrapper<TrackInfo>()
                //先where ID=id 然后根据OrderNum倒叙排，limit1获取第一个
                //也就是获取到了最大的OrderNum的那一行数据
                .eq(TrackInfo::getAlbumId, trackInfoVo.getAlbumId())
                .orderByDesc(TrackInfo::getOrderNum)
                .last(" limit 1")
        );

        //设置为一，如果maxnum为空，直接传入1，不为空加一再传
        Integer newOrder_num = 1;
        if (trackInfoMaxNum != null) {
            newOrder_num = trackInfoMaxNum.getOrderNum() + 1;
        }
        trackInfo.setOrderNum(newOrder_num);
        trackInfoMapper.insert(trackInfo);

        //## -- 每个声音有四个统计数据，四个统计数据初始化0
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
        this.saveTrackStat(trackInfo.getId(), "0702");
        this.saveTrackStat(trackInfo.getId(), "0703");
        this.saveTrackStat(trackInfo.getId(), "0704");

        //## -- 修改操作，把声音所在专辑，include_track_count包含声音数量+1
        //根据专辑id查询专辑数据
        //获取声音数量值 + 1
        //调用方法修改
        AlbumInfo albumInfo = albumInfoService.getById(trackInfo.getAlbumId());
        int includeTrackCount = albumInfo.getIncludeTrackCount() + 1;
        albumInfo.setIncludeTrackCount(includeTrackCount);
        albumInfoService.updateById(albumInfo);

    }

    @Override
    public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
        trackInfoQuery.setUserId(AuthContextHolder.getUserId());
        return trackInfoMapper.findUserTrackPage(trackListVoPage, trackInfoQuery);
    }

    @Override
    public void removeTrackInfo(Long id) {
        //# 1 把声音所在的专辑里面包含声音数量值-1 album_info
        // 根据专辑id查询声音所在的专辑数据
        // 根据声音id获取专辑id
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        Long albumId = trackInfo.getAlbumId();

        // 根据专辑id获取专辑数据
        AlbumInfo albumInfo = albumInfoService.getById(albumId);
        // 获取包含声音数量 -1
        Integer newInclueCount = albumInfo.getIncludeTrackCount() - 1;
        albumInfo.setIncludeTrackCount(newInclueCount);

        //调用方法修改
        albumInfoService.updateById(albumInfo);


        //# 2 根据声音id删除track_info表数据
        trackInfoMapper.deleteById(id);

        //# 3 根据声音id删除track_stat表数据
        LambdaQueryWrapper<TrackStat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TrackStat::getTrackId, id);
        trackStatMapper.delete(wrapper);

        //# 4 删除腾讯云声音文件
        // 调用腾讯云接口实现
        vodService.removeTrackInfo(trackInfo.getMediaFileId());
    }

    //修改声音
    @Override
    public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
        //1 根据声音id获取声音数据
        TrackInfo trackInfo = trackInfoMapper.selectById(id);

        //获取声音文件fieldid
        String mediaFileId_database = trackInfo.getMediaFileId();

        BeanUtils.copyProperties(trackInfoVo, trackInfo);

        //比较数据库里面mediaFileId 和 页面传递 mediaFileId是否相同
        String mediaFileId_page = trackInfoVo.getMediaFileId();
        if (!mediaFileId_database.equals(mediaFileId_page)) {
            //获取最新声音文件数据
            TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackInfoTenx(mediaFileId_page);

            trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
            trackInfo.setMediaType(trackMediaInfoVo.getType());
            trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
            trackInfo.setMediaSize(trackMediaInfoVo.getSize());

            // 删除云点播声音
            vodService.removeTrackInfo(mediaFileId_database);
        }

        trackInfoMapper.updateById(trackInfo);
    }

    @Override
    public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> pageParam, Long albumId, Long userId) {
        IPage<AlbumTrackListVo> pageModel = trackInfoMapper.findAlbumTrackPage(pageParam, albumId);
        //getRecords获取IPage里的List
        List<AlbumTrackListVo> trackListVoList = pageModel.getRecords();
        AlbumInfo albumInfo = albumInfoService.getById(albumId);
        Assert.notNull(albumInfo, "专辑对象不能为空");

        //0101免费 0102vip免费 0103付费
        String payType = albumInfo.getPayType();

        //不是登录状态
        if (userId == null) {
            if (!"0101".equals(payType)) {
                //如果不是免费，那就要查它免费试看几集
                Integer tracksForFree = albumInfo.getTracksForFree();
                List<AlbumTrackListVo> albumTrackListVoList = trackListVoList.stream()
                        //查到后，过滤出排名小于免费集数的，合并成集合返回
                        .filter(albumTrackListVo -> albumTrackListVo.getOrderNum().intValue() > tracksForFree)
                        .collect(Collectors.toList());
                //显示付费
                if (!CollectionUtils.isEmpty(albumTrackListVoList)) {
                    albumTrackListVoList.forEach(albumTrackListVo -> {
                        // 显示付费通知
                        albumTrackListVo.setIsShowPaidMark(true);
                    });
                }
            }
        } else {
            boolean flag = false;
            if ("0102".equals(payType)) {
                Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
                UserInfoVo userInfoVo = userInfoVoResult.getData();
                Integer isVip = userInfoVo.getIsVip();
                flag = isVip.intValue() == 0;

                Date vipExpireTime = userInfoVo.getVipExpireTime();
                if (isVip.intValue() == 1 && vipExpireTime.before(new Date())) {
                    flag = true;
                }
            } else if ("0103".equals(payType)) {//付费
                flag = true;
            }

            //如果付费就这样
            if (flag) {
                List<AlbumTrackListVo> albumTrackListVoList = trackListVoList.stream()
                        .filter(albumTrackListVo -> albumTrackListVo.getOrderNum().intValue() > albumInfo.getTracksForFree())
                        .collect(Collectors.toList());
                //albumTrackListVoList里面声音，查询判断是否购买过
                if (!CollectionUtils.isEmpty(albumTrackListVoList)) {

                    //声音id列表获取到
                    List<Long> trackIdList = albumTrackListVoList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
                    //远程调用：根据userid 、专辑id、声音id查询，用户是否购买专辑 或者是否购买声音
                    Result<Map<Long, Integer>> result = userInfoFeignClient.userIsPaidTrack(userId, albumId, trackIdList);
                    // 返回map集合
                    // map的key是声音id  value：是否购买过 1买过，0 没有购买
                    Map<Long, Integer> map = result.getData();

                    albumTrackListVoList.forEach(albumTrackListVo -> {
//                Long trackId = albumTrackListVo.getTrackId();
//                Integer isPaid = map.get(trackId);
//                if(isPaid == 1) {
//                   albumTrackListVo.setIsShowPaidMark(false);
//                } else {
//                   albumTrackListVo.setIsShowPaidMark(true);
//                }
                        boolean isBuy = map.get(albumTrackListVo.getTrackId()) == 1 ? false : true;
                        albumTrackListVo.setIsShowPaidMark(isBuy);
                    });
                }

            }
        }
        return pageModel;
    }

    @Override
    public void updatePlayNum(TrackStatMqVo trackStatMqVo) {

        LambdaQueryWrapper<TrackStat> wrapper = new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, trackStatMqVo.getTrackId()).eq(TrackStat::getStatType, "0701");
        TrackStat trackStat = trackStatMapper.selectOne(wrapper);
        trackStat.setStatNum(trackStat.getStatNum() + 1);
        trackStatMapper.update(trackStat, wrapper);

    }

    @Override
    public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount) {
        // 根据声音Id 获取到声音对象
        TrackInfo trackInfo = this.getById(trackId);
        Assert.notNull(trackInfo, "声音对象不能为空");

        // 获取已支付的声音id列表
        Result<List<Long>> trackIdListResult = userInfoFeignClient.findUserPaidTrackList(trackInfo.getAlbumId());
        Assert.notNull(trackIdListResult);
        List<Long> trackIdList = trackIdListResult.getData();
        Assert.notNull(trackIdList);
        // 声明一个声音对象集合
        List<TrackInfo> trackInfoList = new ArrayList<>();
        if (trackCount > 0) {
            // 构建查询条件
            LambdaQueryWrapper<TrackInfo> trackInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            trackInfoLambdaQueryWrapper.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId());
            trackInfoLambdaQueryWrapper.gt(TrackInfo::getOrderNum, trackInfo.getOrderNum());
            trackInfoLambdaQueryWrapper.orderByAsc(TrackInfo::getOrderNum);
            if (!CollectionUtils.isEmpty(trackIdList)) {
                trackInfoLambdaQueryWrapper.notIn(TrackInfo::getId, trackIdList);
            }
            trackInfoLambdaQueryWrapper.last("limit " + trackCount);
            trackInfoList = this.list(trackInfoLambdaQueryWrapper);
        } else {
            trackInfoList.add(trackInfo);
        }
        // 返回当前集合对象
        return trackInfoList;
    }


    //获取用户声音分集购买支付列表
    //在点击某集购买时有选项，选择本集、后十集、后二十集、全集等
    //需要判断选择的选项里有没有购买过的
    @Override
    public List<Map<String, Object>> findUserTrackPaidList(Long trackId, Long userId) {
        //获取声音对象
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        Long albumId = trackInfo.getAlbumId();
        AlbumInfo albumInfo = albumInfoService.getById(albumId);
        //根据专辑id获取到用户购买过的声音id集合
        Result<List<Long>> userPaidTrackIdListResult = userInfoFeignClient.findUserPaidTrackList(albumId);
        //List为null抛出异常  另一种情况[]    size是不是0
        Assert.notNull(userPaidTrackIdListResult, "专辑Id集合为空");
        List<Long> paidTrackIdList = userPaidTrackIdListResult.getData();
        Assert.notNull(paidTrackIdList, "声音专辑Id为null");

        //获取当前专辑并且大于当前声音的全部声音Id
        List<TrackInfo> trackInfoList = trackInfoMapper.selectList(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId).gt(TrackInfo::getOrderNum, trackInfo.getOrderNum()).select(TrackInfo::getId));
        List<Long> afterTrackIdAllList = trackInfoList.stream().map(TrackInfo::getId).collect(Collectors.toList());

        //去除已经支付的
        //isEmpty是判断长度是不是0
        List<Long> unPaidtrackIdList = new ArrayList<>();
        if (CollectionUtils.isEmpty(paidTrackIdList)) {
            unPaidtrackIdList = afterTrackIdAllList;
        } else {
            //过滤已支付的剩下的未支付
            unPaidtrackIdList = afterTrackIdAllList.stream().filter(itemId -> !paidTrackIdList.contains(itemId)).collect(Collectors.toList());
        }
        //构造声音分集购买数据列表
        List<Map<String, Object>> list = new ArrayList<>();
        //需要付款的集数有 19
        //本集
        if (unPaidtrackIdList.size() >= 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", "本集");
            map.put("price", albumInfo.getPrice());
            map.put("trackCount", 0);
            list.add(map);
        }
        if (unPaidtrackIdList.size() > 0 && unPaidtrackIdList.size() <= 10) {
            Map<String, Object> map = new HashMap<>();
            int count = unPaidtrackIdList.size();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
            map.put("name", "后" + unPaidtrackIdList.size() + "集");
            map.put("price", price);
            map.put("trackCount", count);
            list.add(map);
        }
        // 19
        if (unPaidtrackIdList.size() > 10) {
            Map<String, Object> map = new HashMap<>();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(10));
            map.put("name", "后10集");
            map.put("price", price);
            map.put("trackCount", 10);
            list.add(map);
        }
        // 后20集
        if (unPaidtrackIdList.size() > 10 && unPaidtrackIdList.size() <= 20) {
            Map<String, Object> map = new HashMap<>();
            int count = unPaidtrackIdList.size();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
            map.put("name", "后" + count + "集");
            map.put("price", price);
            map.put("trackCount", count);
            list.add(map);
        }
        if (unPaidtrackIdList.size() > 20) {
            Map<String, Object> map = new HashMap<>();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(20));
            map.put("name", "后20集");
            map.put("price", price);
            map.put("trackCount", 20);
            list.add(map);
        }

        //后30集
        if (unPaidtrackIdList.size() > 20 && unPaidtrackIdList.size() <= 30) {
            Map<String, Object> map = new HashMap<>();
            int count = unPaidtrackIdList.size();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
            map.put("name", "后" + count + "集");
            map.put("price", price);
            map.put("trackCount", count);
            list.add(map);
        }
        if (unPaidtrackIdList.size() > 30) {
            Map<String, Object> map = new HashMap<>();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(30));
            map.put("name", "后30集");
            map.put("price", price);
            map.put("trackCount", 30);
            list.add(map);
        }

        //后50集
        if (unPaidtrackIdList.size() > 30 && unPaidtrackIdList.size() <= 50) {
            Map<String, Object> map = new HashMap<>();
            int count = unPaidtrackIdList.size();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
            map.put("name", "后" + count + "集");
            map.put("price", price);
            map.put("trackCount", count);
            list.add(map);
        }
        // 最多购买50集;
        if (unPaidtrackIdList.size() > 50) {
            Map<String, Object> map = new HashMap<>();
            BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(50));
            map.put("name", "后50集");
            map.put("price", price);
            map.put("trackCount", 50);
            list.add(map);
        }
        return list;
    }


    @Autowired
    private TrackStatMapper trackStatMapper;

    private void saveTrackStat(Long trackId, String trackType) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(trackType);
        trackStat.setStatNum(0);
        this.trackStatMapper.insert(trackStat);
    }
}
